package com.example.huadu_server.websocket.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.huadu_server.config.Response;
import com.example.huadu_server.house.entity.HouseImage;
import com.example.huadu_server.house.mapper.HouseImageMapper;
import com.example.huadu_server.landlord.entity.Landlord;
import com.example.huadu_server.landlord.mapper.LandlordMapper;
import com.example.huadu_server.user.entity.User;
import com.example.huadu_server.user.mapper.UserMapper;
import com.example.huadu_server.websocket.WebSocketServer;
import com.example.huadu_server.websocket.dto.ConversationDTO;
import com.example.huadu_server.websocket.dto.MessageDTO;
import com.example.huadu_server.websocket.entity.Conversation;
import com.example.huadu_server.websocket.entity.Message;
import com.example.huadu_server.websocket.mapper.ConversationMapper;
import com.example.huadu_server.websocket.mapper.MessageMapper;
import com.example.huadu_server.websocket.service.ChatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class ChatServiceImpl implements ChatService {

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LandlordMapper landlordMapper;

    @Autowired
    private ConversationMapper conversationMapper;

    @Autowired
    private HouseImageMapper houseImageMapper;

    @Autowired
    private JavaMailSender mailSender;  // 注入 JavaMailSender


    @Value("${spring.mail.username}")  // 从配置文件中注入发件人邮箱
    private String senderEmail;
    /**
     * 发送消息
     *
     * @param messageDTO 消息内容
     * @return
     */
    @Override
    public Response<Map<String, Object>> saveMessage(MessageDTO messageDTO) {
        try {
            QueryWrapper<Conversation> query = new QueryWrapper<>();
            query.and(wrapper -> wrapper.eq("user_id", messageDTO.getSenderId())
                            .eq("landlord_id", messageDTO.getReceiverId())
                            .eq("house_id", messageDTO.getHouseId()))
                    .or(wrapper -> wrapper.eq("user_id", messageDTO.getReceiverId())
                            .eq("landlord_id", messageDTO.getSenderId())
                            .eq("house_id", messageDTO.getHouseId()));

            Conversation conversation = conversationMapper.selectOne(query);

            // 存储消息
            Message message = new Message();
            message.setSenderId(messageDTO.getSenderId());
            message.setReceiverId(messageDTO.getReceiverId());
            message.setConversationId(conversation.getId());
            message.setHouseId(messageDTO.getHouseId());
            message.setContent(messageDTO.getContent());
            message.setSentAt(new Timestamp(System.currentTimeMillis()));
            message.setIsRead(false);
            message.setIsReminderSent(false);

            messageMapper.insert(message);

            // 更新会话的最后更新时间
            updateConversationTimestamp(conversation.getId());
            return new Response<>(200, "消息发送成功", null);

        } catch (Exception e) {
            return new Response<>(500, "发送失败：" + e.getMessage(), null);
        }
    }


    // 定时任务：每五分钟检查一次未读消息
    @Scheduled(fixedRate = 5 * 60 * 1000)
    public void checkUnreadMessagesAndSendEmail() {
        // 计算5分钟前的时间
        long fiveMinutesAgo = System.currentTimeMillis() - 5 * 60 * 1000;

        // 查询未读、超过5分钟且未发送过提醒的消息
        List<Message> unreadMessages = messageMapper.selectList(
                new QueryWrapper<Message>()
                        .eq("is_read", false)
                        .eq("is_reminder_sent", false)
                        .lt("sent_at", new Timestamp(fiveMinutesAgo))
        );

        // 如果查询到至少一条符合条件的消息，则执行后续逻辑
        if (unreadMessages != null && !unreadMessages.isEmpty()) {
            // 取第一条消息
            Message firstMessage = unreadMessages.get(0);

            // 发送提醒邮件给房东
            Integer landlordId = firstMessage.getReceiverId();
            Landlord landlord = landlordMapper.selectById(landlordId);
            if (landlord != null) {
                String email = landlord.getEmail();
                if (email != null && !email.isEmpty()) {
                    SimpleMailMessage mailMessage = new SimpleMailMessage();
                    mailMessage.setFrom(senderEmail);  // 发件人邮箱
                    mailMessage.setTo(email);            // 房东的邮箱
                    mailMessage.setSubject("花都优居平台");
                    mailMessage.setText("未读消息提醒：亲爱的房东，您有新的消息，请及时查看。");

                    try {
                        mailSender.send(mailMessage);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            // 计算以第一条消息发送时间为起点，未来10分钟的时间区间
            Timestamp startTime = firstMessage.getSentAt();
            Timestamp endTime = new Timestamp(startTime.getTime() + 10 * 60 * 1000);

            // 更新发送时间在 [startTime, endTime) 内的所有未提醒消息，标记为已提醒
            QueryWrapper<Message> updateWrapper = new QueryWrapper<>();
            updateWrapper.eq("is_reminder_sent", false)
                    .ge("sent_at", startTime)
                    .lt("sent_at", endTime);

            Message updateMessage = new Message();
            updateMessage.setIsReminderSent(true);
            messageMapper.update(updateMessage, updateWrapper);
        }
    }




    /**
     * 更新会话的时间
     *
     * @param conversationId
     */
    private void updateConversationTimestamp(Integer conversationId) {
        // 更新 `conversation` 表的 `updated_at` 字段
        Conversation conversation = new Conversation();
        conversation.setUpdatedAt(new Timestamp(System.currentTimeMillis())); // 当前时间作为更新时间

        conversationMapper.update(conversation,
                new QueryWrapper<Conversation>().eq("id", conversationId));
    }

    /**
     * 获取用户的所有会话及房东信息
     *
     * @param userId 用户 ID
     * @return 会话列表
     */
    @Override
    public Response<List<ConversationDTO>> getConversationsByUserId(Integer userId) {
        try {
            // 查询该用户的所有会话
            QueryWrapper<Conversation> query = new QueryWrapper<>();
            query.eq("user_id", userId);
            query.orderByDesc("updated_at"); // 按更新时间倒序排序
            List<Conversation> conversations = conversationMapper.selectList(query);

            if (conversations.isEmpty()) {
                return new Response<>(404, "没有找到会话", null);
            }

            List<ConversationDTO> conversationDTOs = new ArrayList<>();
            for (Conversation conversation : conversations) {
                // 使用会话ID查找房东信息
                Integer landlordId = conversation.getLandlordId();
                Landlord landlord = landlordMapper.selectById(landlordId);

                // 使用会话ID查找用户信息
                Integer currentUserId = conversation.getUserId();
                User user = userMapper.selectById(currentUserId);  // 假设有userMapper来查询用户信息

                // 查询该会话中来自对方的未读消息数量
                Integer unreadMessagesCount = Math.toIntExact(messageMapper.selectCount(
                        new QueryWrapper<Message>()
                                .eq("conversation_id", conversation.getId())
                                .eq("is_read", false)
                                .ne("sender_id", userId)  // 排除当前用户，获取来自对方的消息
                ));

                // 查询房源的第一张图片
                String houseFirstImage = null;
                Integer houseId = conversation.getHouseId();
                if (houseId != null) {
                    QueryWrapper<HouseImage> imageQuery = new QueryWrapper<>();
                    imageQuery.eq("house_id", houseId)
                            .last("LIMIT 1");  // 只取第一条
                    HouseImage firstImage = houseImageMapper.selectOne(imageQuery);
                    if (firstImage != null) {
                        houseFirstImage = firstImage.getImageUrl();
                    }
                }

                // 将会话和房东信息封装到ConversationDTO中
                ConversationDTO conversationDTO = new ConversationDTO();
                conversationDTO.setConversationId(conversation.getId());
                conversationDTO.setUserId(conversation.getUserId());
                conversationDTO.setLandlordId(conversation.getLandlordId());
                conversationDTO.setHouseId(conversation.getHouseId());
                conversationDTO.setHouseImage(houseFirstImage); // 设置房源第一张图片
                conversationDTO.setCreatedAt(conversation.getCreatedAt());
                conversationDTO.setUpdatedAt(conversation.getUpdatedAt());
                conversationDTO.setUnReadCount(unreadMessagesCount); // 设置未读消息数量

                // 添加用户信息
                if (user != null) {
                    conversationDTO.setUserName(user.getUsername());
                    conversationDTO.setUserLogo(user.getLogo());
                }

                // 添加房东信息
                if (landlord != null) {
                    conversationDTO.setLandlordName(landlord.getUsername());
                    conversationDTO.setLandlordLogo(landlord.getLogo());
                }

                conversationDTOs.add(conversationDTO);
            }

            return new Response<>(200, "查询成功", conversationDTOs);

        } catch (Exception e) {
            return new Response<>(500, "查询失败：" + e.getMessage(), null);
        }
    }


    /**
     * 获取房东的所有会话及用户信息
     *
     * @param landlordId 房东 ID
     * @return 会话列表
     */
    @Override
    public Response<List<ConversationDTO>> getConversationsByLandlordId(Integer landlordId) {
        try {
            // 查询该房东的所有会话
            QueryWrapper<Conversation> query = new QueryWrapper<>();
            query.eq("landlord_id", landlordId);
            query.orderByDesc("updated_at"); // 按更新时间倒序排序

            List<Conversation> conversations = conversationMapper.selectList(query);

            if (conversations.isEmpty()) {
                return new Response<>(404, "没有找到会话", null);
            }

            List<ConversationDTO> conversationDTOs = new ArrayList<>();
            for (Conversation conversation : conversations) {
                // 使用会话ID查找用户信息
                Integer userId = conversation.getUserId();
                User user = userMapper.selectById(userId);

                // 使用会话ID查找用户信息
                Integer currentlandlordId = conversation.getLandlordId();
                Landlord landlord = landlordMapper.selectById(currentlandlordId);

                // 查询该会话中来自对方的未读消息数量
                Integer unreadMessagesCount = Math.toIntExact(messageMapper.selectCount(
                        new QueryWrapper<Message>()
                                .eq("conversation_id", conversation.getId())
                                .eq("is_read", false)
                                .ne("sender_id", landlordId)  // 排除当前用户，获取来自对方的消息
                ));

                // 查询房源的第一张图片
                String houseFirstImage = null;
                Integer houseId = conversation.getHouseId();
                if (houseId != null) {
                    QueryWrapper<HouseImage> imageQuery = new QueryWrapper<>();
                    imageQuery.eq("house_id", houseId)
                            .last("LIMIT 1");  // 只取第一条
                    HouseImage firstImage = houseImageMapper.selectOne(imageQuery);
                    if (firstImage != null) {
                        houseFirstImage = firstImage.getImageUrl();
                    }
                }

                // 将会话和用户信息封装到ConversationDTO中
                ConversationDTO conversationDTO = new ConversationDTO();
                conversationDTO.setConversationId(conversation.getId());
                conversationDTO.setUserId(conversation.getUserId());
                conversationDTO.setLandlordId(conversation.getLandlordId());
                conversationDTO.setHouseId(conversation.getHouseId());
                conversationDTO.setHouseImage(houseFirstImage);
                conversationDTO.setCreatedAt(conversation.getCreatedAt());
                conversationDTO.setUpdatedAt(conversation.getUpdatedAt());
                conversationDTO.setUnReadCount(unreadMessagesCount); // 设置未读消息数量

                // 添加用户信息
                if (user != null) {
                    conversationDTO.setUserName(user.getUsername());
                    conversationDTO.setUserLogo(user.getLogo());
                }

                // 添加房东信息
                if (landlord != null) {
                    conversationDTO.setLandlordName(landlord.getUsername());
                    conversationDTO.setLandlordLogo(landlord.getLogo());
                }

                conversationDTOs.add(conversationDTO);
            }

            return new Response<>(200, "查询成功", conversationDTOs);

        } catch (Exception e) {
            return new Response<>(500, "查询失败：" + e.getMessage(), null);
        }
    }


    /**
     * 获取会话的所有消息
     *
     * @param conversationId 会话 ID
     * @return
     */
    @Override
    public Response<List<Message>> getMessagesByConversationId(Integer conversationId) {
        try {
            // 查询该会话的所有消息
            List<Message> messages = messageMapper.selectList(
                    new QueryWrapper<Message>().eq("conversation_id", conversationId)
                            .orderByAsc("sent_at")  // 按发送时间升序排序
            );

            if (messages.isEmpty()) {
                return new Response<>(404, "没有找到消息", null);
            }

            return new Response<>(200, "查询成功", messages);

        } catch (Exception e) {
            return new Response<>(500, "查询失败：" + e.getMessage(), null);
        }
    }

    /**
     * 创建会话
     *
     * @param messageDTO
     * @return
     */
    @Override
    public Response<Conversation> createConversation(MessageDTO messageDTO) {
        try {
            // 查询是否已有会话（考虑双方互换的情况）
            QueryWrapper<Conversation> query = new QueryWrapper<>();
            query.and(wrapper -> wrapper.eq("user_id", messageDTO.getSenderId())
                            .eq("landlord_id", messageDTO.getReceiverId())
                            .eq("house_id", messageDTO.getHouseId()))
                    .or(wrapper -> wrapper.eq("user_id", messageDTO.getReceiverId())
                            .eq("landlord_id", messageDTO.getSenderId())
                            .eq("house_id", messageDTO.getHouseId()));
            Conversation conversation = conversationMapper.selectOne(query);
            Timestamp now = new Timestamp(System.currentTimeMillis());
            if (conversation != null) {
                // 会话已存在，直接返回
                return new Response<>(200, "会话已存在", conversation);
            }

            // 会话不存在，创建新的会话
            Conversation newConversation = new Conversation();
            newConversation.setUserId(messageDTO.getSenderId());
            newConversation.setLandlordId(messageDTO.getReceiverId());
            newConversation.setHouseId(messageDTO.getHouseId());
            newConversation.setCreatedAt(now);
            newConversation.setUpdatedAt(now);
            conversationMapper.insert(newConversation);

            // 插入默认欢迎消息，由用户发出（可以根据需要修改默认内容）
            Message defaultMessage = new Message();
            defaultMessage.setSenderId(messageDTO.getSenderId());
            defaultMessage.setReceiverId(messageDTO.getReceiverId());
            defaultMessage.setConversationId(newConversation.getId());
            defaultMessage.setHouseId(messageDTO.getHouseId());
            defaultMessage.setContent("房东您好（此消息为默认招呼语）");
            defaultMessage.setSentAt(now);
            defaultMessage.setIsRead(false);
            messageMapper.insert(defaultMessage);

            return new Response<>(200, "会话创建成功", newConversation);
        } catch (Exception e) {
            return new Response<>(500, "会话创建失败：" + e.getMessage(), null);
        }
    }

    /**
     * 标记会话中的消息为已读
     *
     * @param conversationId 会话 ID
     * @return
     */
    @Override
    public Response<String> markMessagesAsRead(Integer conversationId, Integer viewerId) {
        try {
            // 更新条件：指定会话中未读且 sender_id 不等于 viewerId 的消息
            QueryWrapper<Message> query = new QueryWrapper<>();
            query.eq("conversation_id", conversationId)
                    .eq("is_read", false)
                    .ne("sender_id", viewerId);

            Message updateMsg = new Message();
            updateMsg.setIsRead(true);

            int updatedCount = messageMapper.update(updateMsg, query);

            // 根据 conversationId 查询会话记录，确定双方的 ID
            Conversation conversation = conversationMapper.selectById(conversationId);
            if (conversation != null) {
                // 构造通知 payload
                String payload = "{\"type\":\"READ_STATUS\",\"conversationId\":" + conversationId + "}";
                // 判断当前阅读者是谁
                // 如果 viewerId 等于 conversation.getUserId()，说明是用户在阅读，
                // 那么目标推送给房东，存储的 key 为 "landlordId-userId"
                if (conversation.getUserId().equals(viewerId)) {
                    WebSocketServer.sendMessageToTarget(conversation.getLandlordId(), conversation.getUserId(), payload);
                } else {
                    // 否则，viewerId 为房东，目标推送给用户，存储的 key 为 "userId-landlordId"
                    WebSocketServer.sendMessageToTarget(conversation.getUserId(), conversation.getLandlordId(), payload);
                }
            }
            return new Response<>(200, "标记已读成功，共更新 " + updatedCount + " 条消息", null);
        } catch (Exception e) {
            return new Response<>(500, "标记已读失败：" + e.getMessage(), null);
        }
    }


    /**
     * 获取指定会话中某个用户的未读消息数量
     *
     * @param conversationId 会话 ID
     * @param userId         用户 ID
     * @return 未读消息数量
     */
    @Override
    public Response<Integer> getUnreadCountByUserId(Integer conversationId, Integer userId) {
        try {
            // 查询该会话中来自对方的未读消息数量
            Integer unreadCount = Math.toIntExact(messageMapper.selectCount(
                    new QueryWrapper<Message>()
                            .eq("conversation_id", conversationId)
                            .eq("is_read", false)
                            .ne("sender_id", userId)  // 排除当前用户，获取来自对方的未读消息
            ));

            return new Response<>(200, "查询成功", unreadCount);
        } catch (Exception e) {
            return new Response<>(500, "查询失败：" + e.getMessage(), null);
        }
    }
}
